#include "STreeComboBox.h"

#include <core/StyleMgr.h>

#include <QStylePainter>

////////////////////////////////////////////////////////
//	STreeComboBox
////////////////////////////////////////////////////////
STreeComboBox::STreeComboBox(QWidget* parent, /*= nullptr*/ bool bShowInvert,
                             QString strColor, QString strBorderColor,
                             int itemHeight, int dropHeight)
    : SComboBox(parent, strColor, strBorderColor), m_bShowInvert(bShowInvert) {
  m_pTree =
      new STreeComboWidget(this, bShowInvert, false, itemHeight, dropHeight);
  this->setModel(m_pTree->model());
  this->setView(m_pTree);
  connect(m_pTree, &STreeComboWidget::itemSelectChanged, this,
          &STreeComboBox::onTreeItemSelectChanged);
}

STreeComboBox::~STreeComboBox() {}

void STreeComboBox::setTreeData(STreeData& treeData) {
  STreeComboWidget* pView = static_cast<STreeComboWidget*>(view());
  if (!pView) return;
  pView->setTreeData(treeData);
}

void STreeComboBox::setTreeEnable(bool enable) {
  if (m_pTree) {
    m_pTree->setEnabled(enable);
  }

  if (!enable) {
    m_pTree->clearSelect();
  }

  setEnabled(enable);

  if (enable) {
    setStyleSheet(m_styleSheet);
  } else {
    QString styleSheet =
        QString(
            "QComboBox						{color:#%1; "
            "padding: 4px 5px 4px 8px; border-radius:2px;border:1px solid #%4; "
            "background-color:#%2;}"
            "QComboBox:hover				{background-color:#%5;}"
            "QComboBox:on					"
            "{color:#%4;border:1px solid "
            "#%4;background-color:#%2;border-radius:2px;}"
            "QComboBox:disable				{color:#%7; border:1px "
            "solid #%7; background-color:#%2;}"
            "QComboBox::drop-down			"
            "{subcontrol-origin:padding;subcontrol-position:top right; "
            "border-radius:2px; width:20px;}"
            "QComboBox::down-arrow:on		"
            "{border-image:url(:/widgets/image/dropdown_up/"
            "dropdown_up_disabled.png);}"
            "QComboBox::down-arrow			"
            "{border-image:url(:/widgets/image/dropdown_down/"
            "dropdown_down_disabled.png);}"
            "QComboBox QAbstractItemView	{outline:0px;border:1px solid "
            "#%3; "
            "background-color:#%6;border-radius:2px;margin-top:2px;margin-"
            "bottom:2px;}"
            "QComboBox QAbstractItemView::item			"
            "{padding-left:4px;color:#%1;height:24px;background-color:#%6;}"
            "QComboBox QAbstractItemView::item:hover	{background-color:#%4;}"
            "QComboBox QAbstractItemView::item:selected	"
            "{color:#%4;background-image:url(:/widgets/image/dropdown_check/"
            "dropdown_check_pressed.png);background-origin:content;background-"
            "repeat:no-repeat;background-position:right;}")
            .arg(StyleMgr::instance().color("TipsBorder").rgb(), 0, 16)
            .arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16)
            .arg(StyleMgr::instance().color("TipsBorder").rgb(), 0, 16)
            .arg(StyleMgr::instance().color("TipsBorder").rgb(), 0, 16)
            .arg(StyleMgr::instance().color("TipsBorder").rgb(), 0, 16)
            .arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16)
            .arg(StyleMgr::instance().color("TipsBorder").rgb(), 0, 16);

    setStyleSheet(styleSheet);
  }
}

void STreeComboBox::setDefaultString(const QString& strDefault) {
  m_strDefault = strDefault;
}

void STreeComboBox::setDropFixedWidth(int width) {
  if (m_pTree) {
    m_pTree->setFixedWidth(width);
  }
}

void STreeComboBox::clearSelect() {
  STreeComboWidget* pView = static_cast<STreeComboWidget*>(view());
  if (!pView) return;
  pView->clearSelect();
}

void STreeComboBox::onTreeItemSelectChanged() {
  QStringList lstText;
  getSelectItemText(lstText);
  m_strText.clear();
  int count = lstText.size();
  if (count > 0) {
    QString szCount = QString(tr("共%1条:", "Total%1:")).arg(count);
    m_strText.append(szCount);
  }

  if (!m_bShowInvert && count > 0) {
    m_strText = m_strDefault;
    m_strText.append(QString(tr("(%1)", "(%1)")).arg(count));
  } else {
    for (int i = 0; i < count; i++) {
      QString txtItem = lstText.at(i);
      if (i > 0) m_strText.append(";");
      m_strText.append(txtItem);
    }
  }

  if (m_strText.isEmpty()) {
    m_strText = m_strDefault;
  }

  update();
  emit itemSelectChanged();
}

QString ElideText(QString& strInfo, const QFont& font, int width) {
  QFontMetrics fontMetrics(font);
  // 如果当前字体下，字符串长度大于指定宽度
  if (fontMetrics.horizontalAdvance(strInfo) > width) {
    strInfo = QFontMetrics(font).elidedText(strInfo, Qt::ElideRight, width);
  }
  return strInfo;
}

void STreeComboBox::paintEvent(QPaintEvent* e) {
  SComboBox::paintEvent(e);
  QColor txtColor = m_showPopup ? StyleMgr::instance().color("Highlight")
                                : StyleMgr::instance().color("TextNormal");
  if (!isEnabled()) {
    txtColor = StyleMgr::instance().color("TipsBorder");
  }

  QStringList lstText;
  getSelectItemText(lstText);
  int count = lstText.size();
  if (!m_bShowInvert) {
    if (!isEnabled()) {
      txtColor = StyleMgr::instance().color("TipsBorder");
    } else if (count > 0) {
      txtColor = StyleMgr::instance().color("Highlight");
    } else {
      txtColor = StyleMgr::instance().color("TextNormal");
    }
  }

  QStylePainter painter(this);
  painter.setRenderHint(QPainter::Antialiasing);

  QStyleOptionComboBox opt;
  initStyleOption(&opt);
  QRect txtRect = style()->subControlRect(QStyle::CC_ComboBox, &opt,
                                          QStyle::SC_ComboBoxEditField, this);
  QString szText = m_strText;
  QFont fn = font();
  QFontMetrics fontMetrics(fn);

  if (fontMetrics.horizontalAdvance(szText) >
      txtRect.width()) {  // 如果当前字体下，字符串长度大于指定宽度
    szText = fontMetrics.elidedText(szText, Qt::ElideRight, txtRect.width());
  }
  painter.setPen(txtColor);
  painter.drawText(txtRect, szText,
                   QTextOption(Qt::AlignLeft | Qt::AlignVCenter));
}

bool STreeComboBox::getSelectItemText(QStringList& lstText) {
  STreeComboWidget* pView = static_cast<STreeComboWidget*>(view());
  if (!pView) return false;
  return pView->getSelectItemText(lstText);
}

const QStringList& STreeComboBox::getSelectItemData() {
  STreeComboWidget* pView = static_cast<STreeComboWidget*>(view());
  assert(pView);

  return pView->getSelectItemData();
}
